/**
@file
	KernelExport.h
@brief

@author
	GengYong
@revision
	2005/11/05 * Created by GengYong.
*/


#ifndef SAF_HEADER_FILE_KERNELEXPORT_H
#define SAF_HEADER_FILE_KERNELEXPORT_H

#include "PerfCounter.h"

namespace SAF
{
	class IKernel;
	class IConfig;
	class IConnection;
	class IServiceModule;
	class IMessageRouter;

	typedef long long StateBits;
	typedef unsigned long COOKIE;

	namespace DEFINE
	{
		const char BUILDERNAME[]		= "Builder";
		const char DESTROYERNAME[]		= "Destroyer";
		const char DESCRIPTIONNAME[]	= "Description";
		const char MESSAGEROUTERNAME[]  = "MessageRouter";
		const char SERVICEMODULENAME[]  = "ServiceModule";
		typedef struct MODULEDESCRIPTION
		{
			enum { VERSION = 1 };
			unsigned long version;
			const char *  classname;
			const char *  copyright;
			const char *  description;
			const char *  timestamp;
		} MODULEDESCRIPTION;	
	}

	namespace KERNEL
	{
		const char INTERNALSTATE[] = "#_internal_state_#";
		const char INITSTATENAME[] = "#_initstate_name_#";
		typedef struct INTERNALCOMMAND
		{
		public:
			enum 
			{ 
				CONNECTIONJOIN		= 0,		//required
				CONNECTIONDROP		= 1,		//required
				CONNECTIONBROKEN	= 2,		//required
				SETSTATEINVALID		= 3,		//optional
//				TERMINATESVC		= 4,		//optional
			};
		public:
			typedef struct CONNECTIONJOIN_tag
			{
				unsigned long	connectionId;
				char			connectionAddr[16];
				unsigned short	connectionPort;
			} CONNECTIONJOIN_tag;	
			typedef struct CONNECTIONHANDLE_tag
			{				
				IConnection * connectionHandle;
			} CONNECTIONHANDLE_tag;	
		} INTERNALCOMMAND;	
	}	


	class IConfig
	{
	public: 
		virtual bool Load(const char * filename) = 0;
		virtual bool Save(const char * filename) = 0;
		virtual bool SetValue(const char * name, const char *) = 0;
		virtual const char * GetValue(const char * name) const = 0;
	public: 
		IConfig() {;}
		virtual ~IConfig() {;}
	};

	class IKernel
	{
	public:
		typedef void (*MessageRouterPlugHook) (IMessageRouter * pullmod, IMessageRouter * plugmod, void *);
		typedef void (*ServiceModulePlugHook) (IServiceModule * pullmod, IServiceModule * plugmod, void *);
	public: 
		IKernel() {;}
		virtual ~IKernel() {;}
	public: 
		virtual IMessageRouter * PlugMessageRouter(const char * name, IMessageRouter *) = 0;
		virtual IMessageRouter * FindMessageRouter(const char * name) const = 0;
		virtual IServiceModule * PlugServiceModule(const char * name, IServiceModule *) = 0;
		virtual IServiceModule * FindServiceModule(const char * name) const = 0;
		virtual void * InstallModulePlugHook(const char * name, MessageRouterPlugHook, void *) const = 0;
		virtual void * InstallModulePlugHook(const char * name, ServiceModulePlugHook, void *) const = 0;
		virtual void UninstallModulePlugHook(void *) const = 0;
		virtual int GetMessageRouterList(IMessageRouter**&) const = 0;
		virtual int GetServiceModuleList(IServiceModule**&) const = 0;
		virtual int GetServiceModuleDiffList(int stateid1, int stateid2, IServiceModule**&) const = 0;
		virtual int GetMessageRouterInitStateId(int index) const = 0;
		virtual int GetServiceModuleCatalog(int index) const = 0;
		virtual const StateBits& GetServiceModuleStateBits(int index) const = 0;
		virtual int GetStateFromName(const char * statename) const = 0;
		virtual void OutputConsole(const char *, ...) const
#if defined(__GNUC__)
		__attribute__ ((format (printf, 2, 3)))
#endif
		= 0;
	};

	class IConnection
	{
	public:
		IConnection(IMessageRouter * owner):m_owner(owner), m_level(0) {;}
		virtual ~IConnection() {;}
	public:	
		virtual bool	EnterState(const char * statename, void *) = 0;
		virtual int		LeaveState() = 0;	
		virtual void *	Store(const char *, const void *, unsigned long size) const = 0;
		virtual void *	Restore(const char *, unsigned long * size) const = 0;
	public: 
		inline int					Level()	const { return m_level; }
		inline IMessageRouter *		Owner()	const { return m_owner; }
	private:
		int					m_level;
		IMessageRouter *	m_owner;
	};


	typedef struct NetMessage
	{
		unsigned short	catalog;
		unsigned short	command;
	} NetMessage;

	typedef struct NetBuffer
	{
		void		*	data;
		unsigned long	size;
	} NetBuffer;

	typedef struct NetPackage
	{
		NetMessage		message;
		NetBuffer		buffer;
		unsigned long	timestamp;
	} NetPackage;


#ifndef MESSAGEDEVICEINTERFACE
#define MESSAGEDEVICEINTERFACE
#endif

	class MESSAGEDEVICEINTERFACE IMessageRouter
	{
	public: 
		virtual bool Init(IKernel*, IConfig*) = 0;
		virtual void Release() = 0;
	public:	
		virtual bool SendNetMessage(const IConnection *, const NetMessage&, const NetBuffer * = 0, unsigned int count_of_buffer = 0) = 0;
		virtual bool RecvNetMessage(IConnection *&, NetPackage&, unsigned int time) = 0;
		virtual bool DropConnection(const IConnection *) = 0;
	public: 
		IMessageRouter() {;}
		virtual ~IMessageRouter() {;}
	};


#ifndef SERVICEPROXYINTERFACE
#define SERVICEPROXYINTERFACE
#endif

	class SERVICEPROXYINTERFACE IServiceModule
	{
	public:	
		virtual bool Init(IKernel*, IConfig*) = 0;
		virtual void Release() = 0;
	public:
		virtual void Process(IConnection *, const NetPackage&) = 0;
		virtual void OnConnectionIncoming(IConnection *, void *&) = 0;
		virtual void OnConnectionOutgoing(IConnection *, void *&) = 0;
	public: 
		IServiceModule() {;}
		virtual ~IServiceModule() {;}
	};
}

#endif	//#ifndef SAF_HEADER_FILE_KERNELEXPORT_H

